package com.fire.control.system.module.warning.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fire.control.system.dto.UserDTO;
import com.fire.control.system.dto.app.AppFileVo;
import com.fire.control.system.dto.app.AppHandleLogVo;
import com.fire.control.system.dto.app.AppHandleVo;
import com.fire.control.system.dto.app.AppWarningInfoVo;
import com.fire.control.system.dto.app.AppWarningLinkmanVo;
import com.fire.control.system.dto.app.AppWorkLogVo;
import com.fire.control.system.entity.Device;
import com.fire.control.system.entity.WarningHandle;
import com.fire.control.system.entity.WarningInfo;
import com.fire.control.system.module.device.dao.DeviceMapper;
import com.fire.control.system.module.file.dao.FileMapper;
import com.fire.control.system.module.file.dao.FileRepository;
import com.fire.control.system.module.warning.dao.WarningHandleMapper;
import com.fire.control.system.module.warning.dao.WarningHandleRepository;
import com.fire.control.system.module.warning.dao.WarningInfoMapper;
import com.fire.control.system.module.warning.dao.WarningInfoRepository;
import com.fire.control.system.module.warning.dao.WarningMapper;
import com.fire.control.system.module.warning.service.AppWarningService;
import com.fire.control.system.statics.ResponseMessage;
import com.fire.control.system.statics.Status_Warning;
import com.fire.control.system.statics.Type_Report;
import com.fire.control.system.statics.Type_Solution;
import com.fire.control.system.statics.Type_SureWarning;
import com.fire.control.system.support.protocol.app.AppRequestProtocol;
import com.fire.control.system.support.protocol.comman.ProtocolSelector;
import com.fire.control.system.support.protocol.comman.ResponseProtocol;
import com.fire.control.system.support.util.ResultPageUtil;
import com.fire.control.system.support.util.StaticValue;
import com.fire.control.system.support.util.XdaoDate;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

/**
 * 
 * @ClassName:  AppWarningServiceImpl
 * @Description:  报警设备业务接口具体实现
 * @author:  xiechengguang
 * @date:  2017年5月12日 下午6:23:25
 *
 */
@Service
public class AppWarningServiceImpl implements AppWarningService {
	@Autowired private WarningInfoRepository warningInfoRepository;
	@Autowired private WarningHandleRepository warningHandleRepository;
	@Autowired private FileMapper fileMapper;
	@Autowired private ProtocolSelector protocolSelector;
	@Autowired private DeviceMapper deviceMapper;
	@Autowired private WarningMapper warningMapper;
	@Autowired private WarningInfoMapper warningInfoMapper;
	@Autowired private WarningHandleMapper warningHandleMapper;
	
	/**
	 * <p>Title: getWarningInfo</p> 
	 * <p>Description: 根据id获取报警详细信息</p> 
	 * @param requestProtocol
	 * @return 
	 * @see com.fire.control.system.module.warning.service.AppWarningService#getWarningInfo(com.fire.control.system.support.protocol.app.AppRequestProtocol)
	 */
	@Override
	public ResponseProtocol getWarningInfo(AppRequestProtocol requestProtocol) {
		ResponseProtocol respProtocol = protocolSelector.choose(requestProtocol);
		
		if(null != requestProtocol) {
			String id = requestProtocol.getId();
			if(id != null) {
				AppWarningInfoVo vo = warningMapper.getDetailById(id);
				if(vo != null) {
	 				vo.setCurrentStatus(Status_Warning.getValue(vo.getCurrentStatus()));
				}
				ResponseMessage.CODE_200.messageToProtocol(respProtocol);
				respProtocol.setDate(new XdaoDate());
				respProtocol.setData(vo);
				return respProtocol;
			}
		}
		ResponseMessage.CODE_400.messageToProtocol(respProtocol);
		respProtocol.setDate(new XdaoDate());
		return respProtocol;
	}


	/**
	 * <p>Title: getLinkman</p> 
	 * <p>Description: 根据报警id获取火灾报警联系人</p> 
	 * @param requestProtocol
	 * @return 
	 * @see com.fire.control.system.module.warning.service.AppWarningService#getLinkman(com.fire.control.system.support.protocol.app.AppRequestProtocol)
	 */
	@Override
	public ResponseProtocol getLinkman(AppRequestProtocol requestProtocol) {
		ResponseProtocol respProtocol = protocolSelector.choose(requestProtocol);
		
		if(null != requestProtocol) {
			String id = requestProtocol.getId();
			
			ResponseMessage.CODE_200.messageToProtocol(respProtocol);
			respProtocol.setDate(new XdaoDate());
			respProtocol.setData(this.getLinkmans(id));
			
			return respProtocol;
			
		}
		ResponseMessage.CODE_400.messageToProtocol(respProtocol);
		respProtocol.setDate(new XdaoDate());
		return respProtocol;
	}
	
	public List getLinkmans(String id) {
		List<AppWarningLinkmanVo> vos = warningInfoMapper.getLinkman(id);
		
		if(vos != null && !vos.isEmpty()) {
			AppWarningLinkmanVo v = vos.get(0);
			AppWarningLinkmanVo vo = new AppWarningLinkmanVo();
			vo.setName(v.getOwner());
			vo.setTelNumber(v.getPhone());
			vo.setIdenty("业主");
			vos.add(vo);
		}
		return vos;
	}

	/**
	 * <p>Title: report</p> 
	 * <p>Description: 火灾现场报告、故障处理说明公共方法
	 * 进入这个方法后，同时将当前状态更改为处理中（processing）</p> 
	 * @param requestProtocol
	 * @return 
	 * @see com.fire.control.system.module.warning.service.AppWarningService#report(com.fire.control.system.support.protocol.app.AppRequestProtocol)
	 */
	@Transactional
	@Override
	public ResponseProtocol report(AppRequestProtocol requestProtocol, UserDTO user) {
		ResponseProtocol respProtocol = protocolSelector.choose(requestProtocol);
		
		if(null != requestProtocol) {
			String id = requestProtocol.getId();
			WarningInfo warningInfo = warningInfoRepository.findOne(id);
			if(null != warningInfo) {
				
				WarningHandle w = new WarningHandle();
				
				w.setUserId(user.getUserId());
				w.setSolutionType(Type_Solution.valueOf("report")); //默认给定为report，如果是故障申报，下面再改为“dispose”
				
				
				w.setReportType(Type_Report.valueOf(requestProtocol.getReportType()));
				
				Type_SureWarning sureWarning = requestProtocol.getSureWarning();
				
				if("misinformation".equals(sureWarning.name()) || "ordinary".equals(sureWarning.name())) {  
					// 如果是误报或普通报警"??"
					warningInfoRepository.updateComplete(id, sureWarning);
				} else if ("fault".equals(sureWarning.name())) {     // 如果是故障申报"dispose"
					warningInfoMapper.updateApplyfor(id, sureWarning);
				} else if ("fire".equals(sureWarning.name())) { //火灾报警，更改状态为处理中"report"
					warningInfoRepository.updateProcessing(id);
				}
				
				
				w.setSolutionDesc(requestProtocol.getWarningDesc());
				/*w.setTrustees(user.getUserId());  //获取app的使用者的  缓存userId
				//TODO w.setEndTime("处理时间");  //页面给的还是系统时间?
				if(true) { //如果页面传过来时间为null,则给出当前系统时间
					w.setEndTime(new XdaoDate());
				}*/
				w.setWarningInfo(warningInfo);
				WarningHandle savedHandle = warningHandleRepository.save(w);
				
				// 保存文件和处理详细到中间表
				String[] ids = requestProtocol.getIds();
				if(ids != null && ids.length > 0) {
					for(String fid : ids) {
						String objectId = w.getId();
						fileMapper.saveFileAndObject(fid, objectId);
					}
				}
				if(savedHandle != null) {
					ResponseMessage.CODE_200.messageToProtocol(respProtocol);
					respProtocol.setDate(new XdaoDate());
					return respProtocol;
				}
			}
		}
		ResponseMessage.CODE_400.messageToProtocol(respProtocol);
		respProtocol.setDate(new XdaoDate());
		return respProtocol;
	}

	/**
	 * <p>Author: xiechengguang</p> 
	 * <p>Title: sureWarning</p> 
	 * <p>Description: 确认报警，前端根据返回成功状态，
	 * 若是火灾报警则跳转到电话报警，若是故障报警则跳转到处理报警页面</p> 
	 * @param requestProtocol
	 * @return 
	 * @see com.fire.control.system.module.warning.service.AppWarningService#getWarnings(com.fire.control.system.support.protocol.app.AppRequestProtocol)
	 */
	@Transactional
	@Override
	public ResponseProtocol sureWarning(AppRequestProtocol requestProtocol) {
		ResponseProtocol respProtocol = protocolSelector.choose(requestProtocol);
		
		if(requestProtocol != null) {
			String id = requestProtocol.getId();
			
			String warningType = requestProtocol.getWarningType();
			// 修改设备 online_status状态
			if("fire_alarm".equals(warningType)) {
				deviceMapper.setOnlineStatus(id, "alarm");
			}else if("device_fault".equals(warningType)) {
				deviceMapper.setOnlineStatus(id, "fault");
			}
			/**默认火警已拨打过一次*/
			WarningHandle w = new WarningHandle();
			w.setSolutionType(Type_Solution.valueOf("report")); 
			w.setReportType(Type_Report.valueOf("report_call"));
			w.setSolutionDesc("已拨打119火警");
			
			// 修改当前处理状态为“处理中”，以及现场确认报警类型
			int result = warningInfoMapper.updateWarningType(id, warningType);
			if(result > 0) {
				ResponseMessage.CODE_200.messageToProtocol(respProtocol);
				respProtocol.setDate(new XdaoDate());
				return respProtocol;
			}
		}
		ResponseMessage.CODE_400.messageToProtocol(respProtocol);
		respProtocol.setDate(new XdaoDate());
		return respProtocol;
	}
	
	/**
	 * <p>Author: xiechengguang</p> 
	 * <p>Title: handles</p> 
	 * <p>Description: 报警处理情况</p> 
	 * @param requestProtocol
	 * @return 
	 * @see com.fire.control.system.module.warning.service.AppWarningService#handles(com.fire.control.system.support.protocol.app.AppRequestProtocol)
	 */
	@Override
	public ResponseProtocol handles(AppRequestProtocol requestProtocol) {
		ResponseProtocol respProtocol = protocolSelector.choose(requestProtocol);
		
		if(requestProtocol != null) {
			String id = requestProtocol.getId();
			
			AppWarningInfoVo vo = warningMapper.getDetailById(id);
			if(vo != null) {
				vo.setCurrentStatus(Status_Warning.getValue(vo.getCurrentStatus()));
				// 根据报警id获取报警处理vo列表
				List<AppHandleVo> appHandleVos =  warningHandleMapper.getHandlesByWarningInfoId(id);
				for(AppHandleVo v : appHandleVos) {
					List<String> files = fileMapper.getFilesByRelationId(v.getId());
					if(files != null && !files.isEmpty()) {
						v.setFiles(this.absoluteUrls(files));
					}
				}
				// 根据报警处理id获取对应文件
				@SuppressWarnings("unchecked")
				List<AppWarningLinkmanVo> linkmans = this.getLinkmans(id);
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("warningInfo", vo);
				map.put("handles", appHandleVos);
				map.put("linkman", linkmans);
				ResponseMessage.CODE_200.messageToProtocol(respProtocol);
				respProtocol.setDate(new XdaoDate());
				respProtocol.setData(map);
				return respProtocol;
			}
		}
		ResponseMessage.CODE_400.messageToProtocol(respProtocol);
		respProtocol.setDate(new XdaoDate());
		return respProtocol;
	}
	

	/**
	 * <p>Author: xiechengguang</p> 
	 * <p>Title: finishWarning</p> 
	 * <p>Description: 火灾报警---完成报警流程</p> 
	 * @param requestProtocol
	 * @return 
	 * @see com.fire.control.system.module.warning.service.AppWarningService#finishWarning(com.fire.control.system.support.protocol.app.AppRequestProtocol)
	 */
	@Override
	public ResponseProtocol finishWarning(AppRequestProtocol requestProtocol) {
		ResponseProtocol respProtocol = protocolSelector.choose(requestProtocol);
		
		if(requestProtocol != null) {
			String id = requestProtocol.getId();
			// 将当前状态从报警中更改为完成
			int result = warningInfoMapper.finishWarning(id);
			if(result > 0) {
				ResponseMessage.CODE_200.messageToProtocol(respProtocol);
				respProtocol.setDate(new XdaoDate());
				respProtocol.setData(result);
				return respProtocol;
			}
		}
		ResponseMessage.CODE_400.messageToProtocol(respProtocol);
		respProtocol.setDate(new XdaoDate());
		return respProtocol;
	}

	/**
	 * <p>Author: xiechengguang</p> 
	 * <p>Title: handleLog</p> 
	 * <p>Description: 我的工作记录---故障/ 误报/ 火警  </p> 
	 * @param requestProtocol
	 * @return 
	 * @see com.fire.control.system.module.warning.service.AppWarningService#handleLog(com.fire.control.system.support.protocol.app.AppRequestProtocol)
	 */
	@Override
	public ResponseProtocol handleLog(AppRequestProtocol requestProtocol, UserDTO user) {
		ResponseProtocol respProtocol = protocolSelector.choose(requestProtocol);
		
		if(requestProtocol != null) {
			int year = requestProtocol.getYear();
			int month = requestProtocol.getMonth();
			String warningType = requestProtocol.getWarningType();
			/**
			 *  分两步骤去拿数据：
			 *  1.根据用户id和报警类型抓取报警处理表数据列表list；
			 *  2.遍历list, 根据报警处理id关联文件表，抓取文件列表
			 */
			Map<String, Object> map = new HashMap<String, Object>();
			// 火灾
			List<AppWorkLogVo> fireList = warningHandleMapper.getFireHandles(user.getUserId(), year, month); 
			this.setFiles(fireList);
			for(AppWorkLogVo vo : fireList) {
				if(vo != null) {
					List<AppHandleLogVo> handles = warningHandleMapper.getFireHandleLog(user.getUserId(), year, month, vo.getWarningId());
					this.setFiless(handles);
					vo.setHandles(handles);
				}
			}
			
			// 报警
			List<AppWorkLogVo> faultList = warningHandleMapper.getFaultHandles(user.getUserId(), year, month); 
			this.setFiles(faultList);
			for(AppWorkLogVo vo : faultList) {
				if(vo != null) {
					List<AppHandleLogVo> handles = warningHandleMapper.getFireHandleLog(user.getUserId(), year, month, vo.getWarningId());
					this.setFiless(handles);
					vo.setHandles(handles);
				}
			}
			
			map.put("fireList", fireList);
			map.put("faultList", faultList);
			
			ResponseMessage.CODE_200.messageToProtocol(respProtocol);
			respProtocol.setDate(new XdaoDate());
			if("fire_alarm".equals(warningType)) { // 如果是火灾
				respProtocol.setData(fireList);
			} else if("device_fault".equals(warningType)) {  // 如果是故障
				respProtocol.setData(faultList);
			} else {
				respProtocol.setData(map);  // 火警、故障、误报都返回
			}
			return respProtocol;
		}
		ResponseMessage.CODE_400.messageToProtocol(respProtocol);
		respProtocol.setDate(new XdaoDate());
		return respProtocol;
	}
	
	public void setFiles(List<AppWorkLogVo> list) {
		for(AppWorkLogVo vo : list) {
			String id = vo.getId();
			List<String> fileList = fileMapper.getFilesByRelationId(id);
			List<String> absoluteUrls = this.absoluteUrls(fileList);
			vo.setFiles(absoluteUrls);
		}
	}
	
	public void setFiless(List<AppHandleLogVo> list) {
		for(AppHandleLogVo vo : list) {
			String id = vo.getId();
			List<String> fileList = fileMapper.getFilesByRelationId(id);
			List<String> absoluteUrls = this.absoluteUrls(fileList);
			vo.setFiles(absoluteUrls);
		}
	}
	
	/**
	 * @author: xiechengguang 
	 * @Title: absoluteUrls   
	 * @Description: 返回绝对路径  
	 * @param:        
	 * @return: List<String>      
	 * @throws
	 */
	public List<String> absoluteUrls(List<String> urls) {
		List<String> returnUrls = new ArrayList<String> ();
		
		if(urls != null && !urls.isEmpty()) {
			for(String url : urls) {
				url = StaticValue.file_server_domain + url;
				returnUrls.add(url);
			}
		}
		return returnUrls;
	}
	

	/**
	 * <p>Author: xiechengguang</p> 
	 * <p>Title: receive</p> 
	 * <p>Description: 接警</p> 
	 * @param requestProtocol
	 * @return 
	 * @see com.fire.control.system.module.warning.service.AppWarningService#receive(com.fire.control.system.support.protocol.app.AppRequestProtocol)
	 */
	@Override
	public ResponseProtocol receive(AppRequestProtocol requestProtocol) {
		ResponseProtocol respProtocol = protocolSelector.choose(requestProtocol);
		
		if(requestProtocol != null) {
			String id = requestProtocol.getId();
			// 将当前状态从报警中更改为 已接警
			int result = warningInfoRepository.receive(id);
			if(result > 0) {
				ResponseMessage.CODE_200.messageToProtocol(respProtocol);
				respProtocol.setDate(new XdaoDate());
				respProtocol.setData(result);
				return respProtocol;
			}
		}
		ResponseMessage.CODE_400.messageToProtocol(respProtocol);
		respProtocol.setDate(new XdaoDate());
		return respProtocol;
	}
	
	

}
